using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Tetrazune
{
    /// <summary>
    /// Represents an image which appears with flair, moves to another location on a straight path,
    /// and fades out as it reaches its destination.  It does all this in constant time, defined by
    /// SlideSprite.AnimationLength
    /// </summary>
    public class SlideSprite : DrawableGameComponent
    {
        private enum SlideStates
        {
            FadingIn = 0, Moving = 1, FadingOut = 2
        }
        public readonly TimeSpan AnimationLength = TimeSpan.FromMilliseconds(1000);
        protected readonly TimeSpan AppearTime = TimeSpan.FromMilliseconds(150);
        protected readonly TimeSpan FadeTime = TimeSpan.FromMilliseconds(300);

        protected readonly float Alpha = 0.85f;

        private Texture2D sprite;
        private Vector2 startLoc;
        private Vector2 endLoc;
        private Vector2 location;
        private SlideStates state = SlideStates.FadingIn;
        private TimeSpan timer = TimeSpan.Zero;
        private SpriteBatch spb;
        private Vector4 color;

        public SlideSprite(Texture2D sprite, Game game, Vector2 start, Vector2 end)
            : base(game)
        {
            this.sprite = sprite;
            startLoc = start;
            endLoc = end;
            location = start;
            color = Color.White.ToVector4();
        }


        public override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);
            float alpha = (state == SlideStates.Moving ? 1.0f :
                state == SlideStates.FadingIn ? TimingRatio(AppearTime) :
                1 - TimingRatio(FadeTime)) * Alpha;
            color.W = alpha;
            spb.Begin(SpriteBlendMode.AlphaBlend);
            spb.Draw(sprite, location, new Color(color));
            spb.End();

        }
        protected override void LoadContent()
        {
            base.LoadContent();
            spb = new SpriteBatch(Game.GraphicsDevice);
        }
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            timer += gameTime.ElapsedGameTime;
            switch (state)
            {
                case SlideStates.FadingIn:
                    if (timer >= AppearTime)
                    {
                        timer -= AppearTime;
                        state = SlideStates.Moving;
                    }
                    break;
                case SlideStates.Moving:
                    if (timer >= AnimationLength - FadeTime - AppearTime)
                    {
                        timer -= (AnimationLength - FadeTime - AppearTime);
                        state = SlideStates.FadingOut;
                    }
                    else
                        UpdateLocation();
                    break;
                case SlideStates.FadingOut:
                    if (timer >= FadeTime)
                        Game.Components.Remove(this);
                    break;
            }
        }

        private void UpdateLocation()
        {
            float ratio = TimingRatio(AnimationLength - FadeTime - AppearTime);
            location.X = MathHelper.Lerp(startLoc.X, endLoc.X, ratio);
            location.Y = MathHelper.Lerp(startLoc.Y, endLoc.Y, ratio);
        }

        private float TimingRatio(TimeSpan timeToReach)
        {
            float ratio = ((float)timer.Ticks) / timeToReach.Ticks;
            return MathHelper.Clamp(ratio, 0, 1);
        }
    }

}